﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;
using SlimDX.Direct3D9;

namespace LibRadiant.Main
{
    public class Camera
    {

        public Camera(D3D9Core context, int width, int height)
        {
            mContext = context;
            mWidth = width;
            mHeight = height;

            //Fixed projection matrix first
            mProjectionMatrix = Matrix.PerspectiveFovLH(mFOV, Aspect, 0.1f, 1000);

            Position = new Vector3(3, 8, 5);

            mViewMatrix = Matrix.LookAtLH(Position, new Vector3(0, 0, 0), new Vector3(0, 1, 0));
        }

        D3D9Core mContext;

        bool mDirtyFlag = true;
        Vector3 mPosition = new Vector3();

        public Vector3 Position
        {
            get { return mPosition; }
            set {
                if (mPosition == value)
                    return;

                mPosition = value;
                mDirtyFlag = true;
            }
        }

        Vector3 mTarget = new Vector3();
        public Vector3 Target
        {
            get { return mTarget; }
            set {
                if (mTarget == value)
                    return;
                mTarget = value;
                mDirtyFlag = true;
            }
        }

        Matrix mViewMatrix = new Matrix();
        public Matrix ViewMatrix
        {
          get {
              if (mDirtyFlag == false)
                  return mViewMatrix;

              mViewMatrix = Matrix.LookAtLH(Position, At, Up);
              mDirtyFlag = false;
              return mViewMatrix;
          }
        }

        Matrix mProjectionMatrix = new Matrix();
        public Matrix ProjectionMatrix
        {
            get { return mProjectionMatrix; }
            set { mProjectionMatrix = value; }
        }

        public Vector3 mRetBuffer = new Vector3();
        public Vector3 At
        {
            get { 
                mRetBuffer.X = mViewMatrix.M13;
                mRetBuffer.Y = mViewMatrix.M23;
                mRetBuffer.Z = mViewMatrix.M33;
                return mRetBuffer;
            }
        }

        public Vector3 Up
        {
            get
            {
                mRetBuffer.X = mViewMatrix.M12;
                mRetBuffer.Y = mViewMatrix.M22;
                mRetBuffer.Z = mViewMatrix.M32;
                return mRetBuffer;
            }
        }

        public Vector3 Left
        {
            get
            {
                mRetBuffer.X = mViewMatrix.M11;
                mRetBuffer.Y = mViewMatrix.M21;
                mRetBuffer.Z = mViewMatrix.M31;
                return mRetBuffer;
            }
        }

        float mFOV = 1.6f;
        int mWidth;
        int mHeight;

        public float Aspect
        {
            get { return (float)mWidth / mHeight; }
        }


        #region exposed methods
        public bool Update(double inTime)
        {
            //mViewMatrix = Matrix;
            mContext.D3DDevice.SetTransform(TransformState.Projection, mProjectionMatrix);
            mContext.D3DDevice.SetTransform(TransformState.View, ViewMatrix);

            return true;
        }

        public void MoveRelative(Vector3 inRelative)
        {
            
            
        }

        #endregion exposed methods


    }
}
